package com.example.link.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.example.common.common.config.bloom.BloomFilterConfig;
import com.example.common.common.config.filter.UserContext;
import com.example.link.entity.ShortLink;
import com.example.link.model.AccessCount;
import com.example.link.model.CreateShortLinkDTO;
import com.example.link.model.LinkVO;
import com.example.link.service.DomainService;
import com.example.link.service.LinkService;
import com.example.link.service.LinkStatsService;
import com.example.link.util.HttpAnalysisUtil;
import lombok.RequiredArgsConstructor;
import com.example.link.mapper.ShortLinkMapper;
import org.springframework.stereotype.Service;
import com.example.common.utils.ShortCodeUtil;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author qwert
 * @version 1.0.0
 * @create 2025/8/17 15:27
 **/
@Service
@RequiredArgsConstructor
public class LinkServiceImpl implements LinkService {
    private final static String HTTP_PREFIX = "http://";
    private final static String DOMAIN_PORT = "8000";

    private final ShortLinkMapper shortLinkMapper;
    private final DomainService domainService;

    private final BloomFilterConfig.BloomFilterWrapper bloomFilterWrapper;
    private final LinkStatsService linkStatsService;
//    private final RBloomFilter<String> userBloomFilter;

    @Override
    public void createLink(CreateShortLinkDTO shortLinkDTO) {
        // 类型校验，访问时间，访问数量
        validatePattern(shortLinkDTO.getLimitType(), shortLinkDTO.getExpiryDate(), shortLinkDTO.getValidityType(), shortLinkDTO.getVisitLimit());

        // 校验域名，校验分组，校验名称
        validateBaseInfo(shortLinkDTO.getDomainId(), shortLinkDTO.getGroupId(), shortLinkDTO.getName());

        // 创建短链接并重命名校验
        String shortUrl = buildShortLink(shortLinkDTO.getOriginalUrl(), domainService.getDomainById(shortLinkDTO.getDomainId()));

        // 获取网站ico
        String favicon = HttpAnalysisUtil.getFaviconFromApi(shortLinkDTO.getOriginalUrl());

        // 持久至数据库
        ShortLink shortLink = BeanUtil.toBean(shortLinkDTO, ShortLink.class);
        shortLink.setShortUrl(shortUrl);
        shortLink.setUserId(UserContext.getCurrentUser().getUserId());
        if (favicon != null) {
            shortLink.setFavicon(favicon);
        }
        shortLinkMapper.insertShortLink(shortLink);
    }

    @Override
    public List<LinkVO> getShortLinks(String groupId, int pageNum, int pageSize, String keyword) {
        // 获取用户分组下的链接数量
        List<ShortLink> shortLinks = shortLinkMapper.queryLinkCountByGroupId(groupId);
        List<AccessCount> todayAccessCount = linkStatsService.getTodayAccessCount();
        List<AccessCount> accessCount = linkStatsService.getAccessCount();
        Map<String, AccessCount> todayCountMap = todayAccessCount.stream()
                .collect(Collectors.toMap(AccessCount::getShortUrl, Function.identity(), (existing, replacement) -> existing));

        Map<String, AccessCount> totalCountMap = accessCount.stream()
                .collect(Collectors.toMap(AccessCount::getShortUrl, Function.identity(), (existing, replacement) -> existing));

        List<LinkVO> list = shortLinks.stream()
                .map(shortLink -> {
                    LinkVO linkVO = BeanUtil.toBean(shortLink, LinkVO.class);

                    // 获取统计数据，如果不存在则使用默认值
                    AccessCount todayCount = todayCountMap.getOrDefault(shortLink.getShortUrl(),
                            new AccessCount(shortLink.getShortUrl(), 0L, 0L, 0L));
                    AccessCount totalCount = totalCountMap.getOrDefault(shortLink.getShortUrl(),
                            new AccessCount(shortLink.getShortUrl(), 0L, 0L, 0L));

                    // 设置统计字段
                    linkVO.setTodayVisits(todayCount.getTotalAccess().intValue());
                    linkVO.setTotalVisits(totalCount.getTotalAccess().intValue());
                    linkVO.setTodayVisitors(todayCount.getUniqueVisitors().intValue());
                    linkVO.setTotalVisitors(totalCount.getUniqueVisitors().intValue());
                    linkVO.setTodayIPs(todayCount.getUniqueIPs().intValue());
                    linkVO.setTotalIPs(totalCount.getUniqueIPs().intValue());

                    return linkVO;
                })
                .toList();
        // 统计分组下链接的数据访问
        return list;
    }

    /**
     * 基础配置校验
     * @param limitType
     * @param expiryDate
     * @param validityType
     * @param visitLimit
     */
    private void validatePattern(String limitType, Date expiryDate, String validityType, Integer visitLimit) {
        // 若存在时间限制，需保证currentDate < expiryDate

        // 若存在访问上限，访问visitLimit需要大于0，小于max
    }

    /**
     * 域名分组名称校验
     * @param domainId
     * @param groupId
     * @param name
     */
    private void validateBaseInfo(String domainId, String groupId, String name) {
        // 用户id匹配域名，分组id，短链查询相同名称
    }

    private String buildShortLink(String originalUrl, String domain) {
        String prefix = HTTP_PREFIX +  domain + ":" + DOMAIN_PORT + "/";
        String shortCode = ShortCodeUtil.generate(originalUrl, UserContext.getCurrentUser().getUserId());
        if (bloomFilterWrapper.exists(shortCode)) {
            throw new RuntimeException("该链接已存在，请更换链接");
        }
        bloomFilterWrapper.add(shortCode);

        return prefix + shortCode;
    }

}
